package me.shurufa.widget.popupwindow;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.PopupWindow;

import com.google.gson.Gson;
import com.sina.weibo.sdk.utils.LogUtil;

import net.qiujuer.genius.blur.StackBlur;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import in.srain.cube.views.ptr.PtrClassicFrameLayout;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import me.shurufa.R;
import me.shurufa.adapter.AllBookAdapter;
import me.shurufa.model.BookListResponse;
import me.shurufa.net.BaseResponse;
import me.shurufa.net.NetworkConstants;
import me.shurufa.net.RequestServerTask;
import me.shurufa.utils.Constants;
import me.shurufa.utils.Global;
import me.shurufa.utils.HttpUtil;
import me.shurufa.utils.LogUtils;
import me.shurufa.utils.NetworkUtils;
import me.shurufa.utils.RecyclerViewStateUtils;
import me.shurufa.utils.Utils;
import me.shurufa.widget.LoadingFooter;
import me.shurufa.widget.recyclerview.EndlessRecyclerOnScrollListener;
import me.shurufa.widget.recyclerview.HeaderAndFooterRecyclerViewAdapter;
import me.shurufa.widget.recyclerview.HeaderSpanSizeLookup;

/**
 * 点击书架页第一项弹出的PopupWindow是个宫格列表
 *
 * @FileName: me.shurufa.widget.popupwindow.ShelvesFavouriteWindow.java
 * @author: kHRYSTAL
 * @email: 723526676@qq.com
 * @date: 2016-02-01 13:28
 */
public class ShelvesFavouriteWindow extends PopupWindow implements View.OnClickListener {

    private View rootView;
    private View blankView;
    private Activity mContext;
    private View popRoot;
    //  blur
    private int mWidth;
    private int mHeight;
    private int statusBarHeight ;
    private Bitmap mBitmap= null;
    private Bitmap overlay = null;

    private Animation mShowAnim;
    PtrClassicFrameLayout ptrRefresh;
    RecyclerView recyclerView;

    ArrayList dataList;
    AllBookAdapter bookAdapter;
    private HeaderAndFooterRecyclerViewAdapter mHeaderAndFooterRecyclerViewAdapter = null;

    public ShelvesFavouriteWindow(Context context){
        super(context);
        mContext = (Activity)context;
        this.setWidth(ViewGroup.LayoutParams.FILL_PARENT);
        this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        this.setBackgroundDrawable(new BitmapDrawable());
        this.setOutsideTouchable(true);
        mShowAnim = AnimationUtils.loadAnimation(context, R.anim.wheelpicker_anim_enter_bottom);
        mShowAnim.setAnimationListener(new ShowAnimationListener());
        LayoutInflater mLayoutInflater = LayoutInflater.from(context);
//findview
        rootView = mLayoutInflater.inflate(R.layout.pop_book_favourite, null);
        blankView = rootView.findViewById(R.id.blank_view);
        popRoot = rootView.findViewById(R.id.pop_root_layout);
        ptrRefresh = (PtrClassicFrameLayout)rootView.findViewById(R.id.ptr_refresh);
        recyclerView = (RecyclerView)rootView.findViewById(R.id.recycler_view);

//init list
        setRefresh();
        dataList = new ArrayList();
        bookAdapter = new AllBookAdapter(this,dataList, Constants.TYPE_FROM_MY_FAVOURITE);
        mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(bookAdapter);
        recyclerView.setAdapter(mHeaderAndFooterRecyclerViewAdapter);
        //setLayoutManager
        GridLayoutManager manager = new GridLayoutManager(context, 3);
        manager.setSpanSizeLookup(new HeaderSpanSizeLookup((HeaderAndFooterRecyclerViewAdapter) recyclerView.getAdapter(), manager.getSpanCount()));
        recyclerView.setLayoutManager(manager);
        recyclerView.addOnScrollListener(mOnScrollListener);
//
        blankView.setOnClickListener(this);
        setContentView(rootView);

        loadFromCache();
    }

    protected String getCacheName() {
        String cacheKey = cacheKey();
        if (TextUtils.isEmpty(cacheKey))
            return null;
        long uid = 0L;
        if (Global.currentUser != null)
            uid = Global.currentUser.uid;
        return uid + "_" + cacheKey;
    }

    protected void bindData(BaseResponse response, boolean isNew) {
        if (isNew && response.success) {
            String fileName = getCacheName();
            if (!TextUtils.isEmpty(fileName)) {
                File file = new File(Global.cacheJsonDir, fileName);
                FileOutputStream fos = null;
                BufferedOutputStream bos = null;
                try {
                    String data = Global.getGson().toJson(response);
                    byte[] bytes = data.getBytes();
                    fos = new FileOutputStream(file);
                    bos = new BufferedOutputStream(fos);
                    bos.write(bytes);
                    // notice
                    bos.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    Utils.closeQuietly(fos);
                    Utils.closeQuietly(bos);
                }
            }
        }
        if (response.success) {
            addDataToList(response, isNew);
        }
    }

    protected void loadFromCache() {
        String fileName = getCacheName();
        if (TextUtils.isEmpty(fileName)) {
            return;
        }
        File file = new File(Global.cacheJsonDir, fileName);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            String data = Utils.readStream(bis);
            LogUtils.kLog().d(data);
            BaseResponse resp = parseData(data);
            if (resp != null) {
                bindData(resp, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            Utils.closeQuietly(fis);
        }
    }

    private EndlessRecyclerOnScrollListener mOnScrollListener = new EndlessRecyclerOnScrollListener() {

        @Override
        public void onLoadNextPage(View view) {
            super.onLoadNextPage(view);

            LoadingFooter.State state = RecyclerViewStateUtils.getFooterViewState(recyclerView);
            if(state == LoadingFooter.State.Loading) {
                LogUtils.kLog().e("the state is Loading, just wait..");
                return;
            }

            if (hasMore) {
                // loading more
                RecyclerViewStateUtils.setFooterViewState(mContext, recyclerView, 10, LoadingFooter.State.Loading, null);
                loadData(mPage);
            } else {
                //the end
                RecyclerViewStateUtils.setFooterViewState(mContext, recyclerView, 10, LoadingFooter.State.TheEnd, null);
            }
        }
    };

    private void setRefresh() {
        ptrRefresh.setResistance(4.2F);
        ptrRefresh.setRatioOfHeaderHeightToRefresh(1.0F);
        ptrRefresh.setDurationToClose(300);
        ptrRefresh.setDurationToCloseHeader(1000);
        ptrRefresh.setLoadingMinTime(500);
        ptrRefresh.setPullToRefresh(false);
        ptrRefresh.setKeepHeaderWhenRefresh(true);
        ptrRefresh.disableWhenHorizontalMove(true);
        ptrRefresh.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout ptrFrameLayout, View view, View view1) {
                boolean canbePullDown = PtrDefaultHandler.checkContentCanBePulledDown(ptrFrameLayout, view, view1);
                return canbePullDown;
            }
            @Override
            public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                refresh();
            }
        });
    }

/////////////////////////////////////////////////////
    protected void addDataToList(BaseResponse response, boolean isNew) {
        BookListResponse resp = (BookListResponse) response;
        if (isNew) {
            bookAdapter.clear();
        }
        bookAdapter.append(resp.data.books);
        bookAdapter.notifyDataSetChanged();
    }

    protected void showEmptyView() {

    }

    protected void hideEmptyView() {

    }

    protected void setHasMore(boolean hasMore) {

    }

    protected BaseResponse parseData(String data) {
        Gson gson = Global.getGson();
        return gson.fromJson(data, BookListResponse.class);
    }

    protected String cacheKey() {
        return "favourite_book";
    }

//Load and Refresh


    public void refresh() {
        ptrRefresh.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (ptrRefresh!=null&&ptrRefresh.isRefreshing()) {
                    ptrRefresh.refreshComplete();
                }
            }
        },2000);
        onRefresh();
    }

    public void onRefresh() {
        mPage=1;
        loadData(1);
    }


    private int mPage;
    private boolean hasMore = true;
    private View.OnClickListener mFooterClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            RecyclerViewStateUtils.setFooterViewState(mContext, recyclerView, 10, LoadingFooter.State.Loading, null);
            loadData(mPage);
        }
    };


    protected void loadData(final int page) {
        if (!NetworkUtils.isNetAvailable(mContext)){
            RecyclerViewStateUtils.setFooterViewState(mContext, recyclerView, 10, LoadingFooter.State.NetWorkError, this.mFooterClick);
        }else {
            RecyclerViewStateUtils.setFooterViewState(recyclerView, LoadingFooter.State.Loading);
            new RequestServerTask<BookListResponse>(BookListResponse.class) {
                @Override
                protected String requestServer() {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("page", String.valueOf(page));
                    params.put("userId",Global.currentUser.uid);
                    params.put("withTotal",1);
                    return HttpUtil.post(NetworkConstants.GET_FAVOURITE_BOOK_BY_USER, params);
                }

                @Override
                protected void onPostExecute(String s) {
                    super.onPostExecute(s);
                    endRefreshing();
                }

                @Override
                protected void onSuccess(BookListResponse result) {
                    //没有更多数据 不能加载更多
                    if (result.data == null ||result.data.books==null|| result.data.books.length == 0) {
                        hasMore = false;
                        RecyclerViewStateUtils.setFooterViewState(recyclerView, LoadingFooter.State.TheEnd);
                    } else {
                        RecyclerViewStateUtils.setFooterViewState(recyclerView, LoadingFooter.State.Normal);
                        hasMore = true;
                        mPage++;
                        bindData(result, page == 1);
                    }
                }
            }.start();
        }
    }

    public void endRefreshing() {
        if (ptrRefresh != null) {
            ptrRefresh.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (ptrRefresh!=null) {
                        ptrRefresh.refreshComplete();
                    }
                }
            }, 500);
        }
    }




/////////////////////////////////////////////////////
    /**
     * 实例化后需要手动调用改方法 用于截图做模糊处理
     */
    public void init(){
        Rect frame = new Rect();
        mContext.getWindow().getDecorView()
                .getWindowVisibleDisplayFrame(frame);
        statusBarHeight = frame.top;
        LogUtils.d("EditDigest", "" + statusBarHeight);
        DisplayMetrics metrics = new DisplayMetrics();
        mContext.getWindowManager().getDefaultDisplay()
                .getMetrics(metrics);
        mWidth = metrics.widthPixels;
        mHeight = metrics.heightPixels;

        setWidth(mWidth);
        setHeight(mHeight);
        mShowAnim.setFillAfter(true);
        mShowAnim.setDuration(500);
    }

    private Bitmap blur(int i) {
        long startMs = System.currentTimeMillis();
        // Is scale
        View view = mContext.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache(true);
        mBitmap = view.getDrawingCache();
        //TODO 去掉通知栏
        int width = mBitmap.getWidth();
        int height =  mBitmap.getHeight();
        mBitmap = Bitmap.createBitmap(mBitmap,0,statusBarHeight,width,height-statusBarHeight);
        height -= statusBarHeight;
        float scaleFactor = 8;//缩放比例
        float radius = 3;//模糊程度

        overlay = Bitmap.createBitmap((int) (width / scaleFactor),(int) (height / scaleFactor),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(overlay);
        canvas.scale(1 / scaleFactor, 1 / scaleFactor);
        Paint paint = new Paint();
        paint.setFlags(Paint.FILTER_BITMAP_FLAG);
        canvas.drawBitmap(mBitmap, 0, 0, paint);
        //is blur
        // Java
        if (i == 1)
            overlay = StackBlur.blur(overlay, (int) radius, false);
            // Bitmap JNI Native
        else if (i == 2)
            overlay = StackBlur.blurNatively(overlay, (int) radius, false);
            // Pixels JNI Native
        else if (i == 3)
            overlay = StackBlur.blurNativelyPixels(overlay, (int) radius, false);

        LogUtils.d("EditDigestWindow", "blur time is:" + (System.currentTimeMillis() - startMs));
        return overlay;
    }

    public void showFavouriteWindow(View anchor,int bottomMargin) {
        android.widget.RelativeLayout.LayoutParams params =
                new android.widget.RelativeLayout.LayoutParams(AbsoluteLayout.LayoutParams.WRAP_CONTENT,
                        AbsoluteLayout.LayoutParams.WRAP_CONTENT);
        params.bottomMargin = bottomMargin;
        params.topMargin = 200;
        params.leftMargin = 18;
        popRoot.setAnimation(mShowAnim);
        //TODO 设置内部控件 Anim
        setAnimationStyle(android.R.style.Animation_Toast);
        //设置背景高斯模糊
        setBackgroundDrawable(new BitmapDrawable(mContext.getResources(), blur(2)));
        //外部是否可以点击
        setOutsideTouchable(true);
        setFocusable(true);
        showAtLocation(anchor, Gravity.BOTTOM, 0, statusBarHeight);
        popRoot.startAnimation(mShowAnim);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.blank_view:
                dismiss();
                break;
        }
    }

    @Override
    public void dismiss() {
        destroy();
        LogUtils.kLog().e("ShelvesWindow.dismiss()");
        super.dismiss();
    }

    public void destroy() {
        if (null != overlay) {
            overlay.recycle();
            overlay = null;
            System.gc();
        }
        if (null != mBitmap) {
            mBitmap.recycle();
            mBitmap = null;
            System.gc();
        }
    }

    private class ShowAnimationListener implements Animation.AnimationListener {
        public void onAnimationEnd(Animation animation) {
            ptrRefresh.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ptrRefresh.autoRefresh(true);
                }
            }, 400);
        }
        public void onAnimationRepeat(Animation animation) {

        }
        public void onAnimationStart(Animation animation) {

        }

    }
}
